<template>
  <c-card>
    <el-form size="default">
      <el-form-item label="交易所：">
        <el-radio-group v-model="type">
          <el-radio value="0">沪深</el-radio>
<!--          <el-radio value="1">上证</el-radio>-->
          <el-radio value="2">创业</el-radio>
          <el-radio value="3">科创</el-radio>
          <el-radio value="4">北交</el-radio>
        </el-radio-group>
      </el-form-item>
<!--      <el-form-item label="价格：">-->
<!--        <el-radio-group v-model="priceType">-->
<!--          <el-radio value="">全部</el-radio>-->
<!--          <el-radio value="0">0~5</el-radio>-->
<!--          <el-radio value="1">5~10</el-radio>-->
<!--          <el-radio value="2">10~20</el-radio>-->
<!--          <el-radio value="3">20~50</el-radio>-->
<!--          <el-radio value="4">50~100</el-radio>-->
<!--          <el-radio value="5">100~3000</el-radio>-->
<!--        </el-radio-group>-->
<!--      </el-form-item>-->
      <el-form-item label="级别：">
        <el-radio-group v-model="typeValue">
          <template v-for="item in typeOptions">
            <el-radio :value="item.value">{{item.label}}</el-radio>
          </template>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="数据：">
        <el-radio-group v-model="page">
          <template v-for="item in pageOptions">
            <el-radio :value="item.value">{{item.label}}</el-radio>
          </template>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="模型：">
        <el-checkbox-group v-model="modelValue">
          <template v-for="item in modelOptions">
            <el-checkbox :value="item.value">{{item.label}}</el-checkbox>
          </template>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item>
        <el-button :disabled="isLoading" type="primary" @click="getList">筛选</el-button>
        <el-button type="success" @click="saveHandle">保存</el-button>
        <el-button link type="primary" @click.stop="detailHandle">
          多图
        </el-button>
      </el-form-item>
    </el-form>
    <el-progress v-if="isLoading" :stroke-width="6" :percentage="percentage" />
  </c-card>

  <c-card>
  <el-table @row-click="rowHandle"  @selectionChange="selectionChange"  :data="tableList" stripe highlight-current-row>
    <el-table-column type="selection" width="50" />
    <el-table-column prop="stockCode" label="股票代码"/>
    <el-table-column prop="stockName" label="股票名称"/>
    <el-table-column prop="bkName" label="行业板块"/>
    <el-table-column prop="price" label="最新价">
      <template #default="{row}">
        <el-text v-if="row.price > 0" type="danger">{{row.price}}</el-text>
        <el-text v-else-if="row.price < 0" type="success">{{row.price}}</el-text>
        <el-text v-else>{{row.price}}</el-text>
      </template>
    </el-table-column>
    <el-table-column prop="ratio" label="涨跌比">
      <template #default="{row}">
        <el-text v-if="row.ratio > 0" type="danger">{{row.ratio}}%</el-text>
        <el-text v-else-if="row.ratio < 0" type="success">{{row.ratio}}%</el-text>
        <el-text v-else>{{row.ratio}}%</el-text>
      </template>
    </el-table-column>
    <el-table-column prop="rise" label="涨跌额">
      <template #default="{row}">
        <el-text v-if="row.rise > 0" type="danger">{{row.rise}}</el-text>
        <el-text v-else-if="row.rise < 0" type="success">{{row.rise}}</el-text>
        <el-text v-else>{{row.rise}}</el-text>
      </template>
    </el-table-column>
    <el-table-column prop="prec" label="昨收"/>
    <el-table-column prop="limitUp" label="涨停"/>
    <el-table-column prop="limitDown" label="跌停"/>
    <el-table-column prop="turnoverRate" label="换手率">
      <template #default="{row}">
        {{row.turnoverRate}}%
      </template>
    </el-table-column>
    <el-table-column prop="peRatio" label="市盈率（动）"/>
    <el-table-column fixed="right" label="操作">
      <template #default="{row}">
        <el-button link type="primary" @click.stop="rcHandle(row)">
          关注
        </el-button>
        <el-button link type="success" @click.stop="dfHandle(row)">东方</el-button>
      </template>
    </el-table-column>
  </el-table>

  </c-card>
</template>

<script setup>
import {computed, provide, reactive, ref} from "vue";
import {getLocalData, getRequestData} from "../../../utils/getData.js";
import {DEL, GET, POST} from "../../../api/index.js";
import {filterStockList, notify, openDf, toStockDetail} from "../../../utils/commonScript.js";
import {getPriceRange, joinOptions, modelOptions, pageOptions, typeOptions} from "../../../utils/listData.js";
import CCard from "../../../c-components/c-card.vue";
import {useRouter} from "vue-router";
import CLCandlestick from "../../../utils/CLCandlestick.js";
import EchartsOption from "../../../utils/EchartsOption.js";

const router = useRouter()
const tableData = ref([])
const tableList = ref([])
const num = ref(0)
const typeValue = ref('30')
const page = ref(60)
const modelValue = ref(['1'])
const isLoading = ref(false)
const allStockData = ref([])
const type = ref('0')
const priceType = ref('')
const percentage = computed(() => {
  return num.value ? Number((num.value * 100 / allStockData.value.length).toFixed(2)) : 0
})
const stockCode = ref('000000')
provide('stockCode', stockCode)
const selectIds = ref([])
const selectNames = ref([])

const dfHandle = (row) => {
  openDf(row.stockCode)
}

const selectionChange = (rows) => {
  selectIds.value = rows.map(item => item.stockCode)
  selectNames.value = rows.map(item => item.stockName)
}
const detailHandle = () => {
  if(selectIds.value.length){
    toStockDetail(router, selectIds.value.join(), selectNames.value.join())
  } else{
    notify('请勾选要显示的股票', 'error')
  }
}

const rowHandle = (row) => {
  toStockDetail(router, row.stockCode, row.stockName)
}

const saveHandle = () => {
  if(tableData.value.length) {
    let params = tableData.value.map(item => {
      return {
        stockCode: item.stockCode,
        mark: modelValue.value.sort().join(','),
        markPrice: item.price,
        level: typeValue.value
      }
    })
    saveMark(params)
  } else {
    notify('请勾选要标记的股票', 'error')
  }

}

const saveMark = (params) => {
  POST('/market/mark', params).then(res => {
    notify('标记成功','success')
  })
}

const selectData = (data, end, stock, resolve, j) => {
  let sIndex = data.klines.length > page.value + 10 ? data.klines.length - page.value : 0
  let lines = data.klines.slice(sIndex).map(item => {
    const oldStart = item.split(',').map((item, i) => {
      return i !== 0 ? Number(item) : item
    });
    return {
      date: oldStart[0],
      open: oldStart[1],
      close: oldStart[2],
      lowest: oldStart[4],
      highest: oldStart[3],
    }
  });

  let klines = new CLCandlestick().getJoinData(lines)
  const macdData = new CLCandlestick().getMacdData(data.klines)
  const dea = macdData.dea;
  const firstDea = dea[dea.length - 1];
  const diff = macdData.diff;
  const macd = macdData.macd;
  // 均线
  const maData = data.klines.slice(sIndex).map(item => {
    const oldStart = item.split(',').map((item, i) => {
      return i !== 0 ? Number(item) : item
    });
    return [oldStart[1], oldStart[2], oldStart[4], oldStart[3]];
  });
  const ma5 = new EchartsOption([],{pageSize: 0, isJoinShow: false, isShowX: false}).calculateMA(5, maData)
  const ma10 = new EchartsOption([], {pageSize: 0, isJoinShow: false, isShowX: false}).calculateMA(10, maData)

  let first = null
  let second = null
  let third = null

  let index = 0

  modelValue.value.forEach(item => {
    switch (item) {
      case '0':
        // 破前低点
        if (klines.length > 0) {
          let min = klines[0]
          let len = klines.length - 1
          for (let i = 1; i < len; i++) {
            min = klines[i].lowest < min.lowest ? klines[i] : min
          }
          if (klines[len].lowest < min.lowest) {
            index += 1
          }
        }
        break
      case '1':
        // 破前高点
        if (klines.length > 0) {
          let max = klines[0]
          let len = klines.length - 1
          for (let i = 1; i < len; i++) {
            max = klines[i].highest > max.highest ? klines[i] : max
          }
          if (klines[len].highest > max.highest) {
            index += 1
          }
        }
        break
      case '2':
        // 底型
        if (klines.length > 3) {
          // 取最近合并后的三条K线数据
          first = klines[klines.length - 1]
          second = klines[klines.length - 2]
          third = klines[klines.length - 3]

          // 判断其是否为底型 低点最低 高点也是最低
          if (second.lowest < first.lowest
              && second.lowest < third.lowest
              && second.highest < first.highest
              && second.highest < third.highest
          ) {
            index += 1
          }
        }
        break
      case '3':
        // 顶型
        if (klines.length > 3) {
          // 取最近合并后的三条K线数据
          first = klines[klines.length - 1]
          second = klines[klines.length - 2]
          third = klines[klines.length - 3]

          // 判断其是否为顶型 低点最高 高点也是最高
          if (second.lowest > first.lowest
              && second.lowest > third.lowest
              && second.highest > first.highest
              && second.highest > third.highest
          ) {
            index += 1
          }
        }
        break
      case '4':
        // diff突破0轴
        first = diff[diff.length - 1];
        second = diff[diff.length - 2];

        if (Number(first) > 0 && Number(second) < 0) {
          index += 1
        }
        break
      case '5':
        // dea突破0轴
        first = dea[dea.length - 1];
        second = dea[dea.length - 2];

        if (Number(first) > 0 && Number(second) < 0) {
          index += 1
        }
        break
      case '6':
        // macd金叉0上
        first = macd[macd.length - 1];
        second = macd[macd.length - 2];

        if (Number(first) > 0 && Number(second) < 0 && Number(firstDea) > 0) {
          index += 1
        }
        break
      case '7':
        // macd金叉0下
        first = macd[macd.length - 1];
        second = macd[macd.length - 2];

        if (Number(first) > 0 && Number(second) < 0 && Number(firstDea) < 0) {
          index += 1
        }
        break
      case '8':
        // 女上位
        if (Number(ma5[ma5.length - 1]) > Number(ma10[ma10.length - 1])) {
          index += 1
        }
        break
      case '9':
        // 男上位
        if (Number(ma5[ma5.length - 1]) < Number(ma10[ma10.length - 1])) {
          index += 1
        }
        break
      case '10':
        // 女变男上
        if (Number(ma5[ma5.length - 1]) < Number(ma10[ma10.length - 1]) && Number(ma5[ma5.length - 2]) > Number(ma10[ma10.length - 2])) {
          index += 1
        }
        break
      case '11':
        // 男变女上
        if (Number(ma5[ma5.length - 2]) < Number(ma10[ma10.length - 2]) && Number(ma5[ma5.length - 1]) > Number(ma10[ma10.length - 1])) {
          index += 1
        }
        break
      case '12':
        // 男女上位未分
        if (Number(ma5[ma5.length - 1]) === Number(ma10[ma10.length - 1])) {
          index += 1
        }
        break
    }
  })

  //全部满足
  if(index === modelValue.value.length) {
    tableData.value.push(stock)

    if(tableData.value.length < 100) {
      tableList.value.push(stock)
    }
  }

  num.value += 1
  if(num.value >= allStockData.value.length){
    isLoading.value = false
  }
  if(j >=end-1) {
    resolve()
  }
}

// 筛选股票
const filterLowerList = (start, end, resolve) => {

  if(start >= end) {
    isLoading.value = false
    return false
  }

  for(let j=start; j<end; j++){
    // 获取日数据
    let stock = allStockData.value[j]

    getRequestData({
      code: stock.stockCode,
      type: typeValue.value
    }, (data) => {
      selectData(data, end, stock, resolve, j)
    }, true)

  }

}

const filterData = (start, end) => {
  return new Promise(resolve => {
    filterLowerList(start, end, resolve)
  })
}

const filterHandle = async () => {
  if(isLoading.value){
    return
  }
  tableData.value = []
  tableList.value = []
  isLoading.value = true
  num.value = 0

  const thread = 10
  const total = allStockData.value.length
// 线程平均下载值
  const avg = total > thread ? parseInt((total / thread).toString()) : 1

// 存储下载完成值
  for (let i = 0; i < Math.min(thread, total); i++) {
    let start = i * avg;
    let end = (i + 1) * avg;
    await filterData(start, end)
    if (i === thread - 1 && thread !== total) {
      // 下载余数部分
      await filterData(end, total)
    }
  }

}

const getList = () => {
  allStockData.value = []
  GET("/market/market/list", {
    type: type.value,
    minPrice: getPriceRange(priceType.value).min || 0,
    maxPrice: getPriceRange(priceType.value).max
  }).then(res => {
    console.log(res)
    // allStockData.value = filterStockList(res.data)
    allStockData.value = res.data

    filterHandle()

  }).catch(() => {

  })
}


const rcHandle = (row) => {
  POST('/market/user', {
    stockCode: row.stockCode,
  }).then(res => {
    notify('关注成功','success')
  })
}

</script>

<style lang="scss" scoped>
.filter-stock{
  .top{
    height: 44vh;
    margin-bottom: 1vh;
    .btn{
      width: 10vw;
      margin: 2vh;
      display: inline-block;
      background-color: #FFFFFF;
      color: #cb2020;
      border: 1px solid #cb2020;
    }
    .tip{
      text-align: right;
      font-size: 1.2vh;
    }
  }
  .bottom{
    height: 45vh;
  }
}
</style>
